<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class ClockInRecord extends Model
{
    use HasFactory;

    protected $fillable = [
        'user_id',
        'employee_id',
        'type',
        'clock_time',
        'work_date',
        'ip_address',
        'latitude',
        'longitude',
        'location_address',
        'device_info',
        'status',
        'attendance_rule_id',
        'late_minutes',
        'early_minutes',
        'exception_reason',
        'is_makeup',
        'makeup_reason',
        'approval_note',
        'approved_by',
        'approved_at',
        'source',
        'extra_data',
    ];

    protected $casts = [
        'clock_time' => 'datetime',
        'work_date' => 'date',
        'latitude' => 'decimal:7',
        'longitude' => 'decimal:7',
        'is_makeup' => 'boolean',
        'approved_at' => 'datetime',
        'extra_data' => 'array',
    ];

    // 常量定义
    const TYPE_CHECK_IN = 'check_in';
    const TYPE_CHECK_OUT = 'check_out';
    const TYPE_MAKEUP = 'makeup';

    const STATUS_NORMAL = 'normal';
    const STATUS_LATE = 'late';
    const STATUS_EARLY = 'early';
    const STATUS_ABSENT = 'absent';
    const STATUS_MAKEUP_PENDING = 'makeup_pending';
    const STATUS_MAKEUP_APPROVED = 'makeup_approved';
    const STATUS_MAKEUP_REJECTED = 'makeup_rejected';

    const SOURCE_MANUAL = 'manual';
    const SOURCE_MACHINE = 'machine';
    const SOURCE_APP = 'app';
    const SOURCE_WEB = 'web';
    const SOURCE_IMPORT = 'import';

    /**
     * 获取用户关系
     */
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    /**
     * 获取员工关系
     */
    public function employee(): BelongsTo
    {
        return $this->belongsTo(Employee::class);
    }

    /**
     * 获取考勤规则关系
     */
    public function attendanceRule(): BelongsTo
    {
        return $this->belongsTo(AttendanceRule::class);
    }

    /**
     * 获取审批人关系
     */
    public function approver(): BelongsTo
    {
        return $this->belongsTo(User::class, 'approved_by');
    }

    /**
     * 作用域：按用户筛选
     */
    public function scopeByUser($query, $userId)
    {
        return $query->where('user_id', $userId);
    }

    /**
     * 作用域：按日期范围筛选
     */
    public function scopeByDateRange($query, $startDate, $endDate)
    {
        return $query->whereBetween('work_date', [$startDate, $endDate]);
    }

    /**
     * 作用域：按类型筛选
     */
    public function scopeByType($query, $type)
    {
        return $query->where('type', $type);
    }

    /**
     * 作用域：按状态筛选
     */
    public function scopeByStatus($query, $status)
    {
        return $query->where('status', $status);
    }

    /**
     * 作用域：补卡记录
     */
    public function scopeMakeup($query)
    {
        return $query->where('is_makeup', true);
    }

    /**
     * 作用域：待审批补卡
     */
    public function scopePendingMakeup($query)
    {
        return $query->where('status', self::STATUS_MAKEUP_PENDING);
    }

    /**
     * 获取打卡类型的显示名称
     */
    public function getTypeNameAttribute()
    {
        return match($this->type) {
            self::TYPE_CHECK_IN => '上班打卡',
            self::TYPE_CHECK_OUT => '下班打卡',
            self::TYPE_MAKEUP => '补卡',
            default => '未知'
        };
    }

    /**
     * 获取状态的显示名称
     */
    public function getStatusNameAttribute()
    {
        return match($this->status) {
            self::STATUS_NORMAL => '正常',
            self::STATUS_LATE => '迟到',
            self::STATUS_EARLY => '早退',
            self::STATUS_ABSENT => '缺勤',
            self::STATUS_MAKEUP_PENDING => '补卡待审批',
            self::STATUS_MAKEUP_APPROVED => '补卡已批准',
            self::STATUS_MAKEUP_REJECTED => '补卡已拒绝',
            default => '未知'
        };
    }

    /**
     * 获取来源的显示名称
     */
    public function getSourceNameAttribute()
    {
        return match($this->source) {
            self::SOURCE_MANUAL => '手动',
            self::SOURCE_MACHINE => '打卡机',
            self::SOURCE_APP => 'APP',
            self::SOURCE_WEB => '网页',
            self::SOURCE_IMPORT => '导入',
            default => '未知'
        };
    }

    /**
     * 检查是否为异常打卡
     */
    public function isException()
    {
        return in_array($this->status, [
            self::STATUS_LATE,
            self::STATUS_EARLY,
            self::STATUS_ABSENT,
            self::STATUS_MAKEUP_PENDING,
            self::STATUS_MAKEUP_REJECTED
        ]);
    }

    /**
     * 计算打卡是否迟到
     */
    public function calculateLateStatus($rule)
    {
        if (!$rule || $this->type !== self::TYPE_CHECK_IN) {
            return false;
        }

        $workStartTime = $rule->work_start_time;
        $toleranceMinutes = $rule->late_tolerance_minutes ?? 10;

        $lateThreshold = $workStartTime->copy()->addMinutes($toleranceMinutes);

        return $this->clock_time->greaterThan($lateThreshold);
    }

    /**
     * 计算打卡是否早退
     */
    public function calculateEarlyStatus($rule)
    {
        if (!$rule || $this->type !== self::TYPE_CHECK_OUT) {
            return false;
        }

        $workEndTime = $rule->work_end_time;
        $toleranceMinutes = $rule->early_leave_tolerance_minutes ?? 10;

        $earlyThreshold = $workEndTime->copy()->subMinutes($toleranceMinutes);

        return $this->clock_time->lessThan($earlyThreshold);
    }
}
